"""
Sing-box内核管理接口
"""
from fastapi import APIRouter, Depends, UploadFile, File
from api.controller.auth import get_current_user
from api.model.user import User
from api.service.singbox_manager import SingBoxManager
from api.utils.response import success, fail
from api.utils.logger import get_logger
from api.utils.async_helper import run_in_executor

logger = get_logger("singbox_controller")
router = APIRouter()


@router.get("/status", response_model=dict)
async def get_singbox_status(
    current_user: User = Depends(get_current_user)
):
    """获取Sing-box安装状态"""
    try:
        # 异步执行检查
        installed, version = await run_in_executor(SingBoxManager.check_singbox_installed)
        
        if installed:
            path = await run_in_executor(SingBoxManager.get_singbox_path)
            return success({
                "installed": True,
                "version": version,
                "path": path
            }, msg=f"Sing-box已安装 (版本: {version})")
        else:
            # 获取最新版本信息 - 异步执行
            success_flag, latest_version, error = await run_in_executor(SingBoxManager.get_latest_version)
            
            return success({
                "installed": False,
                "version": None,
                "path": None,
                "latest_version": latest_version if success_flag else None
            }, msg="Sing-box未安装")
            
    except Exception as e:
        logger.error(f"获取Sing-box状态失败: {e}", exc_info=True)
        return fail(f"获取状态失败: {str(e)}")


@router.get("/latest-version", response_model=dict)
async def get_latest_version(
    current_user: User = Depends(get_current_user)
):
    """获取最新版本信息"""
    try:
        # 异步执行
        success_flag, version, error = await run_in_executor(SingBoxManager.get_latest_version)
        
        if success_flag:
            return success({
                "version": version
            }, msg=f"最新版本: {version}")
        else:
            return fail(error)
            
    except Exception as e:
        logger.error(f"获取最新版本失败: {e}", exc_info=True)
        return fail(f"获取失败: {str(e)}")


@router.post("/upload", response_model=dict)
async def upload_singbox(
    file: UploadFile = File(...),
    current_user: User = Depends(get_current_user)
):
    """上传并安装Sing-box内核压缩包"""
    try:
        # 检查是否已安装 - 异步执行
        installed, version = await run_in_executor(SingBoxManager.check_singbox_installed)
        if installed:
            return fail(f"Sing-box已安装 (版本: {version})，如需重新安装请先卸载")
        
        # 只有管理员可以安装
        if not current_user.is_admin:
            return fail("只有管理员可以上传安装Sing-box内核")
        
        # 检查文件类型（支持多种常见格式）
        allowed_extensions = ('.zip', '.tar.gz', '.tgz', '.tar')
        if not any(file.filename.endswith(ext) for ext in allowed_extensions):
            return fail("仅支持上传ZIP、TAR.GZ或TAR格式的压缩包")
        
        logger.info(f"管理员 {current_user.username} 上传Sing-box安装包: {file.filename}")
        
        # 保存上传的文件 - 异步执行
        import shutil
        from pathlib import Path
        
        upload_path = Path("runtime/singbox") / file.filename
        
        def save_file():
            upload_path.parent.mkdir(parents=True, exist_ok=True)
            with upload_path.open("wb") as buffer:
                shutil.copyfileobj(file.file, buffer)
        
        await run_in_executor(save_file)
        logger.info(f"文件已保存到: {upload_path}")
        
        # 安装 - 异步执行
        success_flag, message = await run_in_executor(SingBoxManager.install_from_file, str(upload_path))
        
        if success_flag:
            # 提取简洁的版本号信息
            installed, version = await run_in_executor(SingBoxManager.check_singbox_installed)
            simple_msg = f"Sing-box {version} 安装成功" if installed else "Sing-box安装成功"
            logger.info(f"Sing-box安装成功: {simple_msg}")
            return success({"version": version}, msg=simple_msg)
        else:
            logger.error(f"Sing-box安装失败: {message}")
            return fail(message)
            
    except Exception as e:
        logger.error(f"上传安装Sing-box失败: {e}", exc_info=True)
        return fail(f"上传安装失败: {str(e)}")


@router.get("/download-info", response_model=dict)
async def get_download_info(
    current_user: User = Depends(get_current_user)
):
    """获取Sing-box下载信息（引导用户手动下载）"""
    try:
        # 异步执行
        os_type, arch = await run_in_executor(SingBoxManager.get_system_info)
        
        # 构建下载文件名（不指定版本）
        if os_type == 'windows':
            filename_pattern = f"sing-box-*-windows-{arch}.zip"
        elif os_type == 'darwin':
            filename_pattern = f"sing-box-*-darwin-{arch}.tar.gz"
        else:  # linux
            filename_pattern = f"sing-box-*-linux-{arch}.tar.gz"
        
        # GitHub releases最新版本页面
        download_url = "https://github.com/SagerNet/sing-box/releases/latest"
        
        return success({
            "system": f"{os_type}-{arch}",
            "filename_pattern": filename_pattern,
            "download_url": download_url,
            "file_size": "约 8-12 MB",
            "instructions": "请在GitHub Releases页面下载对应系统的最新稳定版本压缩包"
        }, msg="获取下载信息成功")
        
    except Exception as e:
        logger.error(f"获取下载信息失败: {e}", exc_info=True)
        return fail(f"获取信息失败: {str(e)}")


@router.delete("/uninstall", response_model=dict)
async def uninstall_singbox(
    current_user: User = Depends(get_current_user)
):
    """卸载Sing-box内核"""
    try:
        # 只有管理员可以卸载
        if not current_user.is_admin:
            return fail("只有管理员可以卸载Sing-box内核")
        
        logger.info(f"管理员 {current_user.username} 开始卸载Sing-box内核")
        
        # 异步执行
        success_flag, message = await run_in_executor(SingBoxManager.remove_singbox)
        
        if success_flag:
            logger.info(f"Sing-box卸载成功: {message}")
            return success(msg=message)
        else:
            logger.error(f"Sing-box卸载失败: {message}")
            return fail(message)
            
    except Exception as e:
        logger.error(f"卸载Sing-box失败: {e}", exc_info=True)
        return fail(f"卸载失败: {str(e)}")


@router.get("/system-info", response_model=dict)
async def get_system_info(
    current_user: User = Depends(get_current_user)
):
    """获取系统信息"""
    try:
        # 异步执行
        os_type, arch = await run_in_executor(SingBoxManager.get_system_info)
        
        return success({
            "os": os_type,
            "arch": arch
        }, msg=f"系统: {os_type}-{arch}")
        
    except Exception as e:
        logger.error(f"获取系统信息失败: {e}", exc_info=True)
        return fail(f"获取失败: {str(e)}")